﻿using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;


namespace Devtm.ServiceModel.Helpers
{


    /// <summary>
    /// Fonctions for work with Xml Serialize
    /// </summary>
    public static class Xml
    {

        /// <summary>
        /// Serialize an object of T type in XML, this method is an extension method to be used by referencing the <see cref="devtm.Serializers"/> namespace.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1816:CallGCSuppressFinalizeCorrectly")]
        public static string SerializeXml<T>(this T obj)
        {
            string serialize1;
            XmlSerializer x = new XmlSerializer(typeof(T));
            MemoryStream fs = new MemoryStream();
            XmlTextWriter w = null;
        
                using (fs = new MemoryStream())
                {
                    using (w = new XmlTextWriter(fs, new UTF8Encoding()))
                    {
                        w.Formatting = Formatting.None;
                        x.Serialize(w, obj);
                        fs.Position = 0;
                        byte[] buffer = new byte[((int)fs.Length) + 1];
                        fs.Read(buffer, 0, (int)fs.Length);

                        serialize1 = Encoding.Default.GetString(buffer, 0, buffer.Length);
                        w.Close();
                    }
                    fs.Close();
                }
            GC.SuppressFinalize(x);
            return serialize1;
        }

        /// <summary>
        /// Unserialize T
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="strdata"></param>
        /// <returns></returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Un"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1816:CallGCSuppressFinalizeCorrectly")]
        public static T UnSerializeXml<T>(this string strdata)
        {
            T mOne;
            byte[] buffer = Encoding.Default.GetBytes(strdata);
            XmlSerializer x = new XmlSerializer(typeof (T));
            MemoryStream mem = null;
            XmlTextReader r = null;

            using (mem = new MemoryStream(buffer))
            {
                using (r = new XmlTextReader(mem))
                {
                    mOne = (T) x.Deserialize(r);
                    r.Close();
                }
                mem.Close();
            }

            GC.SuppressFinalize(x);

            return mOne;

        }

        /// <summary>
        /// Serialize and write in file
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="fichier"></param>
        /// <returns></returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1816:CallGCSuppressFinalizeCorrectly")]
        public static bool SaveXml<T>(this T obj, string fichier)
        {
            bool ret = false;
            XmlSerializer x = new XmlSerializer(typeof (T));
            FileStream fs = null;
            XmlTextWriter w = null;
            
            using (fs = new FileStream(fichier, FileMode.Create))
            {
                using (w = new XmlTextWriter(fs, new UTF8Encoding()))
                {
                    w.Formatting = Formatting.Indented;
                    x.Serialize(w, obj);
                    w.Close();
                    ret = true;
                }
                fs.Close();
            }
            GC.SuppressFinalize(x);
            return ret;
        }



        /// <summary>
        /// Load a file and unserialize
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="fichier"></param>
        /// <returns></returns>
        public static T LoadXml<T>(this T obj, String fichier)
        {
            using (FileStream fs = new FileStream(fichier, FileMode.Open))
            {
                using (XmlTextReader r = new XmlTextReader(fs))
                {
                    XmlSerializer x = new XmlSerializer(typeof(T));
                    obj = (T)x.Deserialize(r);
                    r.Close();
                }
                fs.Close();
            }
            return obj;
        }
    }


}